<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>matt's validation script</title>
<style type="text/css"><!--
body {font-family:verdana,arial;font-size:10pt;color:black;background:white;margin:5px;}
colgroup {background:lightyellow;}
colgroup.attr {background:dodgerblue;color:white;font-weight:bold;white-space:nowrap;}
colgroup.object {background:skyblue;color:#333333;font-weight:bold;}
colgroup.use {background:silver;color:black;font-family:courier new;font-size:8pt;}
table {font-family:verdana,arial;font-size:10pt;color:black;background:white;border:1 solid black;}
td {border-right:1 solid black;border-bottom:1 solid black;vertical-align:top;}
td ul{margin-bottom:0px;}
th {font-size:14pt;text-align:left;border-bottom:2 solid black;border-right:1 solid black;}
caption {font-family:arial,helvetica,sans-serif;font-size:14pt;font-weight:bold;}
hr {color:blue;text-align:center;width:60%;height:2px;margin: 10px;clear:both;}
h1 {width:100%;font-family:arial,helvetica,sans-serif;font-size:18pt;}
h2 {text-align:right;font-family:verdana,helvetica,sans-serif;font-size:10pt;}
small {font-size:8pt; color:silver}
code {background: silver;}
p code {display: block; margin-left:3em;margin-right:3em;padding:10px;border-top:1 solid gray;border-bottom:1 solid gray;}
a:active, a:hover {color:red;text-decoration:underline overline;}
a:link, a:visited {color:blue;text-decoration:none;}
.note {background-color:#ffffcc;padding:10px;border-top:1px solid gold;border-bottom:1px solid gold;}
.exclaim {background-color:yellow;color:black;font-weight:bold;}
div.title {background-color:dodgerblue;color:black;border:2 solid navy;padding:20px;}
--></style>
</head>
<body>
<div class="title">
<h1>matt's javascript 1.2 validation script</h1>
<h2>version 3</h2>
</div>

<p><strong>This script may be re-used and distributed freely provided this header remains intact and all supporting files are included in the distribution.  All documentation and code in this distribution is provided as-is with no warranty of any kind.  If you have questions or suggestions, please use the free discussion forum at <a href="http://groups.yahoo.com/group/validation">http://groups.yahoo.com/group/validation</a>.</strong></p>

<p class="note"><strong>NOTE:</strong> This script may or may not have been tested on x86 client platforms with Windows XP, Microsoft Internet Explorer 6, and Mozilla FireFox 1.5.  While this script should work on all modern browsers, there may be some problems.  <em>This file is no substitute for your own testing.</em></p>

<p>When included properly in a page, this script initializes all methods and functions required to perform validation on all forms within the page. The script generates a new onsubmit event handler for each form, while capturing the current event handler (if it exists).  (Note that your onsubmit function will run AFTER the validation performed by this script.)  This initialization is automatically performed during the parsing of the page.  If you subsequently add more forms or form elements, simply call the <a href="#setup">Validation.setup()</a> method to process the new objects.  Be careful not to overwrite the event handlers generated by this script.</p>

<p><code>Validation.setup();</code></p>

<p>To validate individual form fields, you will need to write script or HTML attributes for each page which sets up the correct <a href="#properties">properties</a> detailing the types of validation.  Include this script in your page, ideally in the HEAD of the document. Paste the following lines into each page requiring validation:</p>
<p><code>
	&lt;script src="PATH_TO_SCRIPT/prototype.js" type="text/javascript"&gt;&lt;/script&gt;<br />
	&lt;script src="PATH_TO_SCRIPT/validation.js" type="text/javascript"&gt;&lt;/script&gt;
</code></p>

<p>View a <a href="validation.htm">sample form</a> which incorporates this validation script.</p>

<hr />

<p>The following list of properties defines the functionality provided.  To incorporate a given property, you will need to write a line of code which "turns on" the check.  The script necessary is listed in the table.  If you limit your users' environment to a browser which supports the getAttribute DOM method, you can write these properties into the HTML of the page instead.  In this case, the properties are not case-sensitive.</p>
<p class="note"><strong>NOTE:</strong> You can prefix the attribute value with "@" to cause the value to be evaluated at run-time as JavaScript.</p>
<p><code>&lt;input name="start-date" display-name="Start Date" type="text" date="MM/YYYY" required="@getRequired()" /&gt;</code></p>

<p class="note"><strong>NOTE:</strong> To ensure consistency in DOM-compliant environments, the ON values of the validation check attributes must be non-null and non-emtpy.  Any textual values other than "false" or "off" should work. I recommend using script to set the properties so your settings can reside in an external file.</p>

<table cellpadding="3" cellspacing="1" style="float:left;">
<caption><a name="PROPERTIES">Supported Properties</caption>
	<thead>
		<colgroup class="attr">
		<colgroup class="object">
		<colgroup>
		<colgroup class="use">
	</thead>
	<tr>
		<th>Property</th>
		<th>Object</th>
		<th>Description</th>
		<th>Use</th>
	</tr>
	<tr>
		<td><a name="AMOUNT">AMOUNT</td>
		<td>Element</td>
		<td>Turns on a dollar amount check for the field; equivalent to CURRENCY.</td>
		<td>oElement.AMOUNT = true;</td>
	</tr>
	<tr>
		<td><a name="AND">AND</td>
		<td>Element</td>
		<td>Sets up a relational validation check.  If any field in the list has a non-whitespace value, then this field must have a non-whitespace value.  You may provide the list as an array of object references, an array of field names as strings, or as a comma-delimited string of field names.</td>
		<td>oElement.AND = asFields;<br />oElement.AND = sFields;<br />oElement.AND = aoFields;</td>
	</tr>
	<tr>
		<td><a name="AUTO-SUBMIT">AUTO-SUBMIT</td>
		<td>Element</td>
		<td>The Element will submit its form onchange.  The auto submit process bypasses the onsubmit event handler.  Ideal for SELECT elements which are used to control page content.  Note: auto submit is cancellable via the onautosubmit event handler.</td>
		<td>oElement["AUTO-SUBMIT"] = true;</td>
	</tr>
	<tr>
		<td><a name="CURRENCY">CURRENCY</td>
		<td>Element</td>
		<td>See <strong><a href="#AMOUNT">AMOUNT</a></strong>.</td>
		<td>oElement.CURRENCY = true;</td>
	</tr>
	<tr>
		<td><a name="DATE">DATE</td>
		<td>Element</td>
		<td>Turns on the date validation check.  Accepted datetime tokens are as follows: M (single- or double-digit month) MM (double-digit month) D (single- or double-digit day) DD (double-digit day) YYYY (four-digit year) HH (double-digit hour) HH24 (double-digit hour on the 24-hour clock) NN (double-digit minutes) SS (double-digit seconds) AP (AM or PM).  Equivalent to DATETIME.</td>
		<td>oElement.DATETIME = true;<br />oElement.DATETIME = "MM/DD/YYYY HH24:NN";<br />oElement.DATETIME = "HH:NN:SS AP";</td>
	</tr>
	<tr>
		<td><a name="DATETIME">DATETIME</td>
		<td>Element</td>
		<td>See <strong><a href="#DATE">DATE</a></strong>.</td>
		<td>oElement.DATETIME = true;<br />oElement.DATETIME = "MM/DD/YYYY HH24:NN";<br />oElement.DATETIME = "HH:NN:SS AP";</td>
	</tr>
	<tr>
		<td><a name="DISPLAY-NAME">DISPLAY-NAME</td>
		<td>Element</td>
		<td>Sets the name of the field used in the auto-generated error messages.  If not set, the script will attempt to use <strong>NAME</strong> then the name of the field as defined in the HTML.</td>
		<td>oElement["DISPLAY-NAME"] = "PO Number";</td>
	</tr>
	<tr>
		<td><a name="EMAIL">EMAIL</td>
		<td>Element</td>
		<td>The field must contain a valid email address format.</td>
		<td>oElement.EMAIL = true;</td>
	</tr>
	<tr>
		<td><a name="FILTER">FILTER</td>
		<td>Element</td>
		<td>Only keystrokes which match the regular expression syntax may be entered in the field. Others are ignored. This property is not supported under Navigator 6 due to browser bugs.</td>
		<td>oElement.FILTER = "[0-9]";<br />oElement.FILTER = /\d/;</td>
	</tr>
	<tr>
		<td><a name="FLOAT">FLOAT</td>
		<td>Element</td>
		<td>Turns on the floating point check for the field. Equivalent to NUMBER.</td>
		<td>oElement.FLOAT = true;</td>
	</tr>
	<tr>
		<td><a name="INITIAL-FOCUS">INITIAL-FOCUS</td>
		<td>Element</td>
		<td>The first element encountered on a page with this attribute turned on will receive focus when the page is processed.</td>
		<td>oElement["INITIAL-FOCUS"] = true;</td>
	</tr>
	<tr>
		<td><a name="INTEGER">INTEGER</td>
		<td>Element</td>
		<td>Turns on the integer validation check.</td>
		<td>oElement.INTEGER = true;</td>
	</tr>
	<tr>
		<td><a name="INVALID-COLOR">INVALID-COLOR</td>
		<td>Element, Form</td>
		<td>Sets the background color of invalid fields. Does not function in NN4.</td>
		<td>oForm["INVALID-COLOR"] = "yellow";</td>
	</tr>
	<tr>
		<td><a name="MAX">MAX</td>
		<td>Element</td>
		<td>Defines the maximum value the field may have.  Available for <strong>INTEGER</strong>, <strong>FLOAT</strong>, <strong>NUMBER</strong>, <strong>AMOUNT</strong>, <strong>CURRENCY</strong>, <strong>DATE</strong>, <strong>DATETIME</strong> fields.  If used with <strong>DATE</strong> or <strong>DATETIME</strong> validation, the value provided must match the same format.</td>
		<td>oElement.MAX = iMax;<br />oElement.MAX = "02/29/2001";</td>
	</tr>
	<tr>
		<td><a name="maxLength">maxLength</td>
		<td>Element</td>
		<td>Turns on the length validation check.  The user's input may be no more than x characters. This property has mixed-case letters due to its inclusion in the object model.  It is really only intended to be used with textarea elements.</td>
		<td>oElement.maxLength = x;</td>
	</tr>
	<tr>
		<td><a name="MESSAGE">MESSAGE</td>
		<td>Element</td>
		<td>Defines an error message which overrides all other validation messages generated from this field. To create an error message that is specific to a given validation check, prefix the check's name to MESSAGE (e.g. for a message specific to the <strong>DATE</strong> validation, use <strong>DATE-MESSAGE</strong>).</td>
		<td>oElement.MESSAGE = sMessage;<br />oElement["REGEXP-MESSAGE"] = sReMessage;</td>
	</tr>
	<tr>
		<td><a name="MIN">MIN</td>
		<td>Element</td>
		<td>Defines the minimum value the field may have.  Available for <strong>INTEGER</strong>, <strong>FLOAT</strong>, <strong>NUMBER</strong>, <strong>AMOUNT</strong>, <strong>CURRENCY</strong>, <strong>DATE</strong>, <strong>DATETIME</strong> fields.  If used with <strong>DATE</strong> or <strong>DATETIME</strong> validation, the value provided must match the same format.</td>
		<td>oElement.MIN = iMin;<br />oElement.MIN = "12/31/2000";</td>
	</tr>
	<tr>
		<td><a name="NAME">NAME</td>
		<td>Element</td>
		<td>Sets the display name of the field in the auto-generated messages. The property only has meaning when set via script since HTML itself is case-insensitive.</td>
		<td>oElement.NAME = "PO Number";</td>
	</tr>
	<tr>
		<td><a name="NUMBER">NUMBER</td>
		<td>Element</td>
		<td>See <strong><a href="#FLOAT">FLOAT</a></strong>.</td>
		<td>oElement.NUMBER = true;</td>
	</tr>
	<tr>
		<td><a name="onaftervalidate">onaftervalidate</td>
		<td>Element</td>
		<td>Pseudo-event enabling script to run just after validation of the INPUT element.  May be cancelled.</td>
		<td>oElement.onaftervalidate = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onaftervalidate">onaftervalidate</td>
		<td>Form</td>
		<td>Pseudo-event enabling script to run just after the FORM validates its elements.  May be cancelled.</td>
		<td>oForm.onaftervalidate = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onautosubmit">onautosubmit</td>
		<td>Element</td>
		<td>Pseudo-event enabling cancellation or processing for automated submit.  May be cancelled.</td>
		<td>oElement.onautosubmit = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onautosubmit">onautosubmit</td>
		<td>Form</td>
		<td>Pseudo-event enabling cancellation or processing for all automated submits within a form.  May be cancelled.</td>
		<td>oForm.onautosubmit = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onaftervalidate">onbeforevalidate</td>
		<td>Element</td>
		<td>Pseudo-event enabling script to run just before validation of the INPUT element.</td>
		<td>oElement.onbeforevalidate = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onbeforevalidate">onbeforevalidate</td>
		<td>Form</td>
		<td>Pseudo-event enabling script to run just before the FORM begins to validate its elements.  May be cancelled.</td>
		<td>oForm.onbeforevalidate = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onreset">onreset</td>
		<td>Element</td>
		<td>Pseudo-event enabling script to run when the form's reset method is called.  Cannot be cancelled.</td>
		<td>oElement.onreset = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onvalidate">onvalidate</a></td>
		<td>Element</td>
		<td>Pseudo-event which fires directly after all default validation for a given form field.  Use this event to trigger custom validation on individual elements.  May be cancelled.</td>
		<td>oElement.onvalidate = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="onvalidatefocus">onvalidatefocus</a></td>
		<td>Element</td>
		<td>Pseudo-event which fires directly before focus is given to the form field which failed validation.  Cannot be cancelled.</td>
		<td>oElement.onvalidatefocus = function () { ... }</td>
	</tr>
	<tr>
		<td><a name="OR">OR</td>
		<td>Element</td>
		<td>Sets up a relational validation check.  If no field in the list has a non-whitespace value, this field must have a non-whitespace value.  You may provide the field list as an array of object references, an array of field names as strings, or as a comma-delimited string of field names.</td>
		<td>oElement.OR = new Array("field1","field2" ... );<br />oElement.OR = new Array(oField1, oField2 ... );<br />oElement.OR = "field1,field2 ... ";</td>
	</tr>
	<tr>
		<td><a name="ORDERED-VALIDATION">ORDERED-VALIDATION</td>
		<td>Form</td>
		<td>When turned on, the elements of the form will be validated based on individual VALIDATION-ORDER properties.  Alternatively, the script can use the tab order of the elements by setting the value of this attribute to "tabindex".  Note: for larger forms, ORDERED-VALIDATION may cause a noticeable delay.</td>
		<td>oForm["ORDERED-VALIDATION"] = true;<br />oForm["ORDERED-VALIDATION"] = "tabIndex";</td>
	</tr>
	<tr>
		<td><a name="PHONE">PHONE</td>
		<td>Element</td>
		<td>The field must contain a valid US phone number.  The check actually calculates the total number of digits.  The number must have ten or eleven digits to be valid. If eleven digits, the first digit must be a 1.</td>
		<td>oElement.PHONE = true;</td>
	</tr>
	<tr>
		<td><a name="REGEXP">REGEXP</td>
		<td>Element</td>
		<td>Apply a user-defined regular expression validation check. Use of the <strong>MESSAGE</strong> or <strong>REGEXP-MESSAGE</strong> properties is strongly encouraged.</td>
		<td>oElement.REGEXP = oRegex;</td>
	</tr>
	<tr>
		<td><a name="REQUIRED">REQUIRED</td>
		<td>Element</td>
		<td>The field must have a non-whitespace value.</td>
		<td>oElement.REQUIRED = true;</td>
	</tr>
	<tr>
		<td><a name="SIGNED">SIGNED</td>
		<td>Element</td>
		<td>When used in combination with <strong>AMOUNT</strong>, <strong>FLOAT</strong>, or <strong>INTEGER</strong>, this attribute further allows the user to use a minus (-) sign in the value.</td>
		<td>oElement.SIGNED = true;</td>
	</tr>
	<tr>
		<td><a name="SUPPRESS-ONCHANGE-MESSAGE">SUPPRESS-ONCHANGE-MESSAGE</td>
		<td>Element, Form</td>
		<td>Prevents error messages from popping up when validation fails in the onchange validator. Turning this property on for the form element covers all fields of that form.</td>
		<td>oForm["SUPPRESS-ONCHANGE-MESSAGE"] = true;</td>
	</tr>
	<tr>
		<td><a name="VALIDATE-ONCHANGE">VALIDATE-ONCHANGE</td>
		<td>Element, Form</td>
		<td>If turned on, the field (or fields of the form) will trigger validation from the onchange event. Turn on <strong>SUPPRESS-ONCHANGE-MESSAGE</strong> to use the DHTML effects for failed validation without popping up an error message; the message will still fire when the form is submitted if the error has not been corrected.</td>
		<td>oElement["VALIDATE-ONCHANGE"] = true;<br />oForm["VALIDATE-ONCHANGE"] = true;</td>
	</tr>
	<tr>
		<td><a name="VALIDATION-ORDER">VALIDATION-ORDER</td>
		<td>Element</td>
		<td>Specifies the ordinal position of the element in the validation queue.  The element's form must have ORDERED-VALIDATION turned on.</td>
		<td>oElement["VALIDATION-ORDER"] = 4;</td>
	</tr>
	<tr>
		<td><a name="VALIDATION-SET">VALIDATION-SET</td>
		<td>Element</td>
		<td>Specifies the element or elements that will be marked by the default markInvalid implementation, yielding a visual representation of a logical validation unit. For example, specify the containing row of a table to be marked as invalid.</td>
		<td>oElement["VALIDATION-SET"] = $("firstName", "middleName", "lastName");</td>
	</tr>
	<tr>
		<td><a name="ZIP">ZIP</td>
		<td>Element</td>
		<td>The field must have a valid US ZIP code. Includes the ZIP+4 format.</td>
		<td>oElement.ZIP = true;</td>
	</tr>
</table>

<hr />
<p>The following table lists the methods generated via the validation script.  They are particularly useful for processing errors generated in the <strong><a href="#onvalidate">onvalidate</a></strong>, <strong><a href="#onbeforevalidate">onbeforevalidate</a></strong> and <strong><a href="#onaftervalidate">onaftervalidate</a></strong> pseudo-events.</p>

<table cellpadding="3" cellspacing="1" style="float:left;">
<caption>Exposed Methods</caption>
	<thead>
		<colgroup class="object">
		<colgroup class="attr">
		<colgroup>
		<colgroup class="use">
	</thead>
	<tr>
		<th>Object</th>
		<th>Method</th>
		<th>Description</th>
		<th>Use</th>
	</tr>
	<tr>
		<td>Validation</td>
		<td><a name="setup">setup</a></td>
		<td>Creates event handlers and methods for all forms and elements that have not already been processed.  If you do not dynamically insert forms or elements into the page, this method is not of use.</td>
		<td>Validation.setup();</td>
	</tr>
	<tr>
		<td>Validation</td>
		<td><a name="add">add</a></td>
		<td><span class="exclaim"><strong>NOTE:</strong> This method is for advanced users.</span> Allows for the addition of validation check routines at run-time. The function provided is re-scoped within the Validation object via the <code style="display:inline">eval</code> function and thus has access to its internal functions; pass a function pointer or an anonymous function declaration. All such routines are applied to each field in the order the functions were added. The function you pass in must accept the element reference and element value as its parameters.</td>
		<td>function functionName(element, value){ ... }<br />Validation.add(functionName);</td>
	</tr>
	<tr>
		<td>Validation.Err</td>
		<td>raise</td>
		<td>Display popup message box with error message.  Gives focus to field if able and selects contents if editable.  Providing an optional word stem lets the Err object search the field for a message specific to the validation error (e.g. setting the stem to "SSN" tells the Err object to search for the "SSN-MESSAGE" property on the element).</td>
		<td>Validation.Err.raise(oElement, sErrorMessage, sStem);</td>
	</tr>
</table>
<hr />
<table cellpadding="3" cellspacing="1" style="float:left;">
<caption>Release Notes</caption>
	<thead>
		<colgroup class="attr">
		<colgroup>
	</thead>
	<tr>
		<td>1.0.0</td>
		<td>Initial publication.</td>
	</tr>
	<tr>
		<td>1.0.1</td>
		<td>
			<ul>
				<li>Removed plus (+) character from SIGNED field format</li>
				<li>Added MIN/MAX check to AMOUNT and FLOAT fields</li>
				<li>Added LENGTH check</li>
				<li>Added comma (,) as acceptable charater in numeric formats</li>
				<li>Added number formatting to MIN/MAX messages</li>
				<li>Minor fixes</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>1.0.2</td>
		<td>
			<ul>
				<li>Fixed date parsing error</li>
				<li>Minor fixes</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.0.0</td>
		<td>
			<ul>
				<li>Enabled stem-based error messaging</li>
				<li>Enabled run-time additions of validation routines</li>
				<li>Enabled DHTML capabilities</li>
				<li>Enabled keypress filtering</li>
				<li>Enabled onchange validation for form fields</li>
				<li>Removed trim prototyped function from String object</li>
				<li>Optimized validation processing by making many data checks mutually exclusive</li>
				<li>oForm.onsubmit now returns true rather than undefined</li>
				<li>Removed add and clear methods on the Validation.Err object</li>
				<li>Enabled onbeforevalidate and onaftervalidate pseudo events for form fields</li>
				<li>Enabled onvalidatefocus event for form fields</li>
				<li>Enabled check to prevent validation of disabled fields</li>
				<li>Expanded date format validation</li>
				<li>Removed NOSPACE, LOWERCASE and UPPERCASE processing</li>
				<li>Enabled CURRENCY synonym for AMOUNT</li>
				<li>Enabled NUMBER synonym for FLOAT</li>
				<li>Enabled DATETIME synonym for DATE</li>
				<li>Enabled MASK validation</li>
				<li>Altered LENGTH validation to read the 'maxLength' property rather than 'length'</li>
				<li>AND and OR checks now validate only the field with the AND/OR attribute rather than triggering validation on the fields listed within the property value.</li>
				<li>Renamed 'valid' method to 'validate' to bring naming into line with existing method/event combinations</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.0.1</td>
		<td>
			<ul>
				<li>Fixed MIN/MAX bug</li>
				<li>Fixed bug in onchange handling</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.0.2</td>
		<td>
			<ul>
				<li>Removed MASK validation check</li>
				<li>Fixed bug in painting invalid elements</li>
				<li>Updated the Validation.add processing</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.1.0</td>
		<td>
			<ul>
				<li>Added AUTO-SUBMIT property</li>
				<li>Added INITIAL-FOCUS property</li>
				<li>Added ordered validation</li>
				<li>Added onreset event for form elements</li>
				<li>Several bug fixes</li>
				<li>Ignore support for non-DOM-compliant browsers</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.1.1</td>
		<td>
			<ul>
				<li>Several bug fixes</li>
				<li>Added logic to disable validation on Mac IE, which has a bug that hinders the script</li>
				<li>Created initial test harness</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.1.2</td>
		<td>
			<ul>
				<li>Fixed bug introduced in 3.1.1 which broke the trim function</li>
				<li>Created trim method on String (which got removed somewhere along the way)</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.1.3</td>
		<td>
			<ul>
				<li>Fixed bug in FILTER processing when form fields are nested within a FIELDSET element.</li>
				<li>Added datetime tokens for single-digit hours (i.e. h, h24)</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.1.4</td>
		<td>
			<ul>
				<li>Added characters to prevent error when the script is run through a size optimizer.  Way to optimize!</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>3.2.0</td>
		<td>
			<ul>
				<li>Re-wrote tests for JsUnit, but still not enough.</li>
				<li>Hitched my wagon to Prototype</li>
				<li>File may now be loaded in the head of the document</li>
				<li>Fixed(?) issue with write access of file form field.</li>
				<li>Added support for run-time evaluation of property values, possibly eliminating the need for relational validation.</li>
				<li>Added auto-marking of required fields. This auto-marking could cause performance degradation on older browsers or large forms. If you experience any difficulties, please post to the group and we'll find a better solution.</li>
				<li>Extracted methods and properties not really specific to validation to separate API</li>
				<li>Implemented message aggregation to display messages all at once in an alert box or a targeted DIV in the page.</li>
				<li>Refactoring validation API to make methods overridable; beginning to provide a simpler means of controlling default settings--NO XML!</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td>Future</td>
		<td>
			<ul>
				<li>Provide mechanism for swapping required/invalid marking</li>
				<li>Extract validation functions as list of objects</li>
			</ul>
		</td>
	</tr>
</table>
</body>
</html>